﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

using BodaNetCommunications.Utilities.ComTypes;

namespace BodaNetCommunications.Utilities.DataLibs
{
    [Obsolete("测试使用，后续转换到其他的单独数据类型的Lib中")]
    public static class ByteArrayHelper
    {
        /// <summary>
        /// 判断两个字节数组是否完全一致
        /// </summary>
        /// <param name="b1"></param>
        /// <param name="b2"></param>
        /// <returns></returns>
        public static bool ByteArrayEquals(byte[] b1, byte[] b2)
        {
            if (b1 == null || b2 == null) return false;
            if (b1.Length == 0 || b2.Length == 0 || b1.Length != b2.Length) return false;
            for (int i = 0; i < b1.Length; i++)
            {
                if (b1[i] != b2[i])
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 自定义截取字节数组
        /// </summary>
        /// <param name="dest"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static byte[] GetByteArray(byte[] dest, int offset, int count)
        {
            if (dest != null && dest.Length >= offset + count)
            {
                byte[] result = new byte[count];
                Array.Copy(dest, offset, result, 0, count);
                return result;
            }
            else
            {
                return null;
            }
        }

        #region 布尔数组转换成字节数组

        public static byte[] BoolArrayToByteArray(bool[] val)
        {
            if (val == null || val.Length == 0) return null;

            int iByteArrLen = 0;

            if (val.Length % 8 == 0)
            {
                iByteArrLen = val.Length / 8;
            }
            else
            {
                iByteArrLen = val.Length / 8 + 1;
            }

            byte[] result = new byte[iByteArrLen];

            for (int i = 0; i < iByteArrLen; i++)
            {
                //比如我们布尔的长度是20,  1-8表示第一个字节，9-16表示第二个字节，剩下的4个布尔

                int total = i == iByteArrLen - 1 ? val.Length - 8 * i : 8;

                for (int j = 0; j < total; j++)
                {
                    result[i] = SetbitValue(result[i], j + 1, val[8 * i + j]);
                }
            }
            return result;
        }

        #endregion 布尔数组转换成字节数组

        #region 给字节某个位赋值

        private static byte SetbitValue(byte data, int index, bool val)
        {
            if (index > 8 || index < 1)
                return 0;
            int v = index < 2 ? index : 2 << index - 2;
            return val ? (byte)(data | v) : (byte)(data & ~v);
        }

        #endregion 给字节某个位赋值

        #region 字符串转换各种类型数组

        public static bool[] GetBoolArray(string val)
        {
            List<bool> Result = new List<bool>();

            if (val.Contains(' '))
            {
                string[] str = Regex.Split(val, "\\s+", RegexOptions.IgnoreCase);

                foreach (var item in str)
                {
                    Result.Add(item.ToLower() == "true" || item == "1");
                }
            }
            else
            {
                Result.Add(val.ToLower() == "true" || val == "1");
            }
            return Result.ToArray();
        }

        public static short[] GetShortArray(string val)
        {
            List<short> Result = new List<short>();

            if (val.Contains(' '))
            {
                string[] str = Regex.Split(val, "\\s+", RegexOptions.IgnoreCase);

                foreach (var item in str)
                {
                    Result.Add(Convert.ToInt16(item));
                }
            }
            else
            {
                Result.Add(Convert.ToInt16(val));
            }
            return Result.ToArray();
        }

        public static ushort[] GetUShortArray(string val)
        {
            List<ushort> Result = new List<ushort>();

            try
            {
                if (val.Contains(' '))
                {
                    string[] str = Regex.Split(val, "\\s+", RegexOptions.IgnoreCase);

                    foreach (var item in str)
                    {
                        Result.Add(Convert.ToUInt16(item));
                    }
                }
                else
                {
                    Result.Add(Convert.ToUInt16(val));
                }
                return Result.ToArray();
            }
            catch (Exception)
            {
                return null;
            }
        }

        public static int[] GetIntArray(string val)
        {
            List<int> Result = new List<int>();

            if (val.Contains(' '))
            {
                string[] str = Regex.Split(val, "\\s+", RegexOptions.IgnoreCase);

                foreach (var item in str)
                {
                    Result.Add(Convert.ToInt32(item));
                }
            }
            else
            {
                Result.Add(Convert.ToInt32(val));
            }
            return Result.ToArray();
        }

        public static uint[] GetUIntArray(string val)
        {
            List<uint> Result = new List<uint>();

            if (val.Contains(' '))
            {
                string[] str = Regex.Split(val, "\\s+", RegexOptions.IgnoreCase);

                foreach (var item in str)
                {
                    Result.Add(Convert.ToUInt32(item));
                }
            }
            else
            {
                Result.Add(Convert.ToUInt32(val));
            }
            return Result.ToArray();
        }

        public static float[] GetFloatArray(string val)
        {
            List<float> Result = new List<float>();

            if (val.Contains(' '))
            {
                string[] str = Regex.Split(val, "\\s+", RegexOptions.IgnoreCase);

                foreach (var item in str)
                {
                    Result.Add(Convert.ToSingle(item));
                }
            }
            else
            {
                Result.Add(Convert.ToSingle(val));
            }
            return Result.ToArray();
        }

        #endregion 字符串转换各种类型数组

        #region 16位整型转换字节数组

        public static byte[] GetByteArrayFrom16Bit(this EndianType dataFormat, short SetValue)
        {
            byte[] ResTemp = BitConverter.GetBytes(SetValue);

            byte[] Res = new byte[2];

            switch (dataFormat)
            {
                case EndianType.ABCD:
                case EndianType.CDAB:
                    Res[0] = ResTemp[1];
                    Res[1] = ResTemp[0];
                    break;

                case EndianType.BADC:
                case EndianType.DCBA:
                    Res = ResTemp;
                    break;

                default:
                    break;
            }
            return Res;
        }

        public static byte[] GetByteArrayFrom16Bit(this EndianType dataFormat, ushort SetValue)
        {
            byte[] ResTemp = BitConverter.GetBytes(SetValue);

            byte[] Res = new byte[2];

            switch (dataFormat)
            {
                case EndianType.ABCD:
                case EndianType.CDAB:
                    Res[0] = ResTemp[1];
                    Res[1] = ResTemp[0];
                    break;

                case EndianType.BADC:
                case EndianType.DCBA:
                    Res = ResTemp;
                    break;

                default:
                    break;
            }
            return Res;
        }

        #endregion 16位整型转换字节数组

        #region 32位数据转换字节数组

        public static byte[] GetByteArrayFrom32Bit(this EndianType dataFormat, float SetValue)
        {
            byte[] ResTemp = BitConverter.GetBytes(SetValue);

            byte[] Res = new byte[4];

            switch (dataFormat)
            {
                case EndianType.ABCD:
                    Res[0] = ResTemp[3];
                    Res[1] = ResTemp[2];
                    Res[2] = ResTemp[1];
                    Res[3] = ResTemp[0];
                    break;

                case EndianType.BADC:
                    Res[0] = ResTemp[2];
                    Res[1] = ResTemp[3];
                    Res[2] = ResTemp[0];
                    Res[3] = ResTemp[1];
                    break;

                case EndianType.CDAB:
                    Res[0] = ResTemp[1];
                    Res[1] = ResTemp[0];
                    Res[2] = ResTemp[3];
                    Res[3] = ResTemp[2];
                    break;

                case EndianType.DCBA:
                    Res[0] = ResTemp[0];
                    Res[1] = ResTemp[1];
                    Res[2] = ResTemp[2];
                    Res[3] = ResTemp[3];
                    break;

                default:
                    break;
            }
            return Res;
        }

        public static byte[] GetByteArrayFrom32Bit(this EndianType dataFormat, int SetValue)
        {
            byte[] ResTemp = BitConverter.GetBytes(SetValue);

            byte[] Res = new byte[4];

            switch (dataFormat)
            {
                case EndianType.ABCD:
                    Res[0] = ResTemp[3];
                    Res[1] = ResTemp[2];
                    Res[2] = ResTemp[1];
                    Res[3] = ResTemp[0];
                    break;

                case EndianType.BADC:
                    Res[0] = ResTemp[2];
                    Res[1] = ResTemp[3];
                    Res[2] = ResTemp[0];
                    Res[3] = ResTemp[1];
                    break;

                case EndianType.CDAB:
                    Res[0] = ResTemp[1];
                    Res[1] = ResTemp[0];
                    Res[2] = ResTemp[3];
                    Res[3] = ResTemp[2];
                    break;

                case EndianType.DCBA:
                    Res[0] = ResTemp[0];
                    Res[1] = ResTemp[1];
                    Res[2] = ResTemp[2];
                    Res[3] = ResTemp[3];
                    break;

                default:
                    break;
            }
            return Res;
        }

        public static byte[] GetByteArrayFrom32Bit(this EndianType dataFormat, uint SetValue)
        {
            byte[] ResTemp = BitConverter.GetBytes(SetValue);

            byte[] Res = new byte[4];

            switch (dataFormat)
            {
                case EndianType.ABCD:
                    Res[0] = ResTemp[3];
                    Res[1] = ResTemp[2];
                    Res[2] = ResTemp[1];
                    Res[3] = ResTemp[0];
                    break;

                case EndianType.BADC:
                    Res[0] = ResTemp[2];
                    Res[1] = ResTemp[3];
                    Res[2] = ResTemp[0];
                    Res[3] = ResTemp[1];
                    break;

                case EndianType.CDAB:
                    Res[0] = ResTemp[1];
                    Res[1] = ResTemp[0];
                    Res[2] = ResTemp[3];
                    Res[3] = ResTemp[2];
                    break;

                case EndianType.DCBA:
                    Res[0] = ResTemp[0];
                    Res[1] = ResTemp[1];
                    Res[2] = ResTemp[2];
                    Res[3] = ResTemp[3];
                    break;

                default:
                    break;
            }
            return Res;
        }

        #endregion 32位数据转换字节数组

        #region 各个类型的数组截取

        public static byte[] Get16ByteArray(this EndianType type, byte[] byteArray, int start)
        {
            if (byteArray != null && byteArray.Length >= start + 2)
            {
                byte[] ResTemp = new byte[2];
                byte[] Res = new byte[2];
                for (int i = 0; i < 2; i++)
                {
                    ResTemp[i] = byteArray[start + i];
                }

                switch (type)
                {
                    case EndianType.ABCD:
                    case EndianType.CDAB:
                        Res[0] = ResTemp[1];
                        Res[1] = ResTemp[0];
                        break;

                    case EndianType.BADC:
                    case EndianType.DCBA:
                        Res = ResTemp;
                        break;
                }

                return Res;
            }
            else
            {
                return null;
            }
        }

        public static byte[] Get32ByteArray(this EndianType type, byte[] byteArray, int start)
        {
            if (byteArray != null && byteArray.Length >= start + 4)
            {
                byte[] ResTemp = new byte[4];
                byte[] Res = new byte[4];
                for (int i = 0; i < 4; i++)
                {
                    ResTemp[i] = byteArray[start + i];
                }

                switch (type)
                {
                    case EndianType.ABCD:
                        Res[0] = ResTemp[3];
                        Res[1] = ResTemp[2];
                        Res[2] = ResTemp[1];
                        Res[3] = ResTemp[0];
                        break;

                    case EndianType.CDAB:
                        Res[0] = ResTemp[1];
                        Res[1] = ResTemp[0];
                        Res[2] = ResTemp[3];
                        Res[3] = ResTemp[2];
                        break;

                    case EndianType.BADC:
                        Res[0] = ResTemp[2];
                        Res[1] = ResTemp[3];
                        Res[2] = ResTemp[0];
                        Res[3] = ResTemp[1];
                        break;

                    case EndianType.DCBA:
                        Res = ResTemp;
                        break;
                }

                return Res;
            }
            else
            {
                return null;
            }
        }

        #endregion 各个类型的数组截取
    }
}